const PI = 3.1415926535897932384626;
const ee = 0.00669342162296594323;
const a = 6378245;

// 检查坐标是否在中国范围外
function outOfChina(lng, lat) {
  return lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271;
}

// 经纬度转换函数
function transform(lng, lat) {
  const lng_r = lng - 105.0;
  const lat_r = lat - 35.0;

  // 转换经度
  let tran_lng = 300.0 + lng_r + 2.0 * lat_r + 0.1 * lng_r * lng_r + 0.1 * lng_r * lat_r + 0.1 * Math.sqrt(Math.abs(lng_r));
  tran_lng += ((20.0 * Math.sin(6.0 * lng_r * PI) + 20.0 * Math.sin(2.0 * lng_r * PI)) * 2.0) / 3.0;
  tran_lng += ((20.0 * Math.sin(lng_r * PI) + 40.0 * Math.sin((lng_r / 3.0) * PI)) * 2.0) / 3.0;
  tran_lng += ((150.0 * Math.sin((lng_r / 12.0) * PI) + 300.0 * Math.sin((lng_r / 30.0) * PI)) * 2.0) / 3.0;

  // 转换纬度
  let tran_lat = -100.0 + 2.0 * lng_r + 3.0 * lat_r + 0.2 * lat_r * lat_r + 0.1 * lng_r * lat_r + 0.2 * Math.sqrt(Math.abs(lng_r));
  tran_lat += ((20.0 * Math.sin(6.0 * lng_r * PI) + 20.0 * Math.sin(2.0 * lng_r * PI)) * 2.0) / 3.0;
  tran_lat += ((20.0 * Math.sin(lat_r * PI) + 40.0 * Math.sin((lat_r / 3.0) * PI)) * 2.0) / 3.0;
  tran_lat += ((160.0 * Math.sin((lat_r / 12.0) * PI) + 320.0 * Math.sin((lat_r * PI) / 30.0)) * 2.0) / 3.0;

  return { tran_lng, tran_lat };
}

// WGS-84 转 GCJ-02
export const WG_to_GCJ = (lng, lat) => {
  if (outOfChina(lng, lat)) {
    return { mglng: "116.397428", mglat: "39.90923" };
  }

  const { tran_lng, tran_lat } = transform(lng, lat);
  const radlat = (lat / 180.0) * PI;
  const magic = Math.sin(radlat);
  const adjustedMagic = 1 - ee * magic * magic;
  const sqrtMagic = Math.sqrt(adjustedMagic);

  const dlat = (tran_lat * 180.0) / (((a * (1 - ee)) / (adjustedMagic * sqrtMagic)) * PI);
  const dlng = (tran_lng * 180.0) / ((a / sqrtMagic) * Math.cos(radlat) * PI);

  const mglat = lat + dlat;
  const mglng = lng + dlng;

  return { mglng, mglat };
};

// GCJ-02 转 WGS-84
export const GCJ_to_WG = (lng, lat) => {
  if (outOfChina(lng, lat)) {
    return { wglng: lng, wglat: lat };
  }

  const { mglng, mglat } = WG_to_GCJ(lng, lat);
  const wglng = lng * 2 - mglng;
  const wglat = lat * 2 - mglat;

  return { wglng, wglat };
};
